package com.cskaoyan.javase._2polymorphic._6exercise;

/**
 * 读程序题
 * 关于对象名.成员方法,如何分析它的调用结果呢?
 * 先分析该对象名的访问范围
 *      如果是一个父类类型的引用,注意访问范围只可能是父类.
 *      但是如果是一个子类类型的引用,访问范围是父类 + 子类
 * 其次,再根据对象的类型不同,分析出执行的结果:
 *      方法调用的结果,要根据对象的具体类型来确定.
 *
 * 除了以上原则,还需要考虑方法调用时,实参匹配的就近原则
 * @since 15:02
 * @author wuguidong@cskaoyan.onaliyun.com
 */

public class Test {
    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new B();
        B b = new B();
        C c = new C();
        D d = new D();
        // AA
        System.out.println("1--" + a1.show(b));
        // AA
        System.out.println("2--" + a1.show(c));
        // AD
        System.out.println("3--" + a1.show(d));

        // BA
        System.out.println("4--" + a2.show(b));
        // BA
        System.out.println("5--" + a2.show(c));
        // AD
        System.out.println("6--" + a2.show(d));

        // BB
        System.out.println("7--" + b.show(b));
        // BB
        System.out.println("8--" + b.show(c));
        // AD
        System.out.println("9--" + b.show(d));
    }
}

class A {
    // A类父类中的独有方法
    public String show(D obj) {
        return ("A and D");
    }

    // 该方法被子类重写了
    public String show(A obj) {
        return ("A and A");
    }
}

class B extends A {
    // B类子类中的独有方法
    public String show(B obj) {
        return ("B and B");
    }

    @Override
    public String show(A obj) {
        return ("B and A");
    }
}

class C extends B {
}

class D extends B {
}